package financial.sharing.center.receivable.service.impl;

import com.github.pagehelper.PageInfo;
import financial.sharing.center.common.enums.AccruedOperationStageEnum;
import financial.sharing.center.common.enums.BillOperationStageEnum;
import financial.sharing.center.common.enums.EnableStatusEnum;
import financial.sharing.center.common.enums.ResponseContext;
import financial.sharing.center.common.utils.BigDecimalUtil;
import financial.sharing.center.receivable.dao.ReceivableBillMapper;
import financial.sharing.center.receivable.model.entity.ReceivableAccrued;
import financial.sharing.center.receivable.model.entity.ReceivableBill;
import financial.sharing.center.receivable.service.ReceivableAccruedService;
import financial.sharing.center.receivable.service.ReceivableBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ReceivableBillServiceImpl
 * @Description TODO
 * @Author guoyuhang
 * @ @csdn https://blog.csdn.net/qq_40788718
 * @Date 2021/5/18
 * @Version 1.0
 */
@Service
public class ReceivableBillServiceImpl implements ReceivableBillService {

    @Autowired
    private ReceivableBillMapper receivableBillMapper;

    @Autowired
    private ReceivableAccruedService receivableAccruedServiceImpl;

    @Override
    public ReceivableBill getReceivableBill(Integer id){
        return this.receivableBillMapper.selectByPrimaryKey(id);
    }

    @Override
    public Integer getBillNumber(ReceivableAccrued receivableAccrued) {
        Example example = new Example(ReceivableBill.class);
        example.createCriteria().andEqualTo("receivableAccruedId",receivableAccrued.getId())
                                .andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue());
        List<ReceivableBill> receivableBillList = this.receivableBillMapper.selectByExample(example);
        return receivableBillList != null ? receivableBillList.size() : 0;
    }

    @Override
    public PageInfo<ReceivableBill> getAllReceivableBill(Integer contractId, Integer accruedId, Integer billId) {
        Example example = new Example(ReceivableBill.class);
        Example.Criteria criteria = example.createCriteria().andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue());
        if (contractId != null && contractId >= 0){
            criteria.andEqualTo("contractId", contractId);
        }
        if (accruedId != null && accruedId >= 0){
            criteria.andEqualTo("receivableAccruedId", accruedId);
        }
        if (billId != null && billId >= 0){
            criteria.andEqualTo("id", billId);
        }
        List<ReceivableBill> receivableBillList = this.receivableBillMapper.selectByExample(example);
        for (ReceivableBill receivableBill : receivableBillList) {
            receivableBill.setBillOperationStatusName(BillOperationStageEnum.int2Enum(receivableBill.getBillOperationStatusValue()).getName());
        }
        return new PageInfo<>(receivableBillList);
    }

    @Override
    public Integer createOneReceivableBill(BigDecimal billAmount, String payableCompanyName, String receivableCompanyName) {
        ReceivableBill receivableBill = new ReceivableBill(billAmount, payableCompanyName, receivableCompanyName);
        int i = this.receivableBillMapper.insert(receivableBill);
        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.创建失败.getValue();
    }

    @Override
    public Integer compileOneReceivableBill(ReceivableBill receivableBill) {
        if (BillOperationStageEnum.已确认.getValue().equals(receivableBill.getBillOperationStatusValue()) && receivableBill.getReceivableAccruedId() != null){
            ReceivableAccrued receivableAccrued = this.receivableAccruedServiceImpl.getReceivableAccrued(receivableBill.getReceivableAccruedId());
            if (receivableAccrued == null){
                return ResponseContext.计提不存在.getValue();
            }
            if (!AccruedOperationStageEnum.勾稽中.getValue().equals(receivableAccrued.getAccruedOperationStageValue())){
                return ResponseContext.计提操作状态不符合.getValue();
            }
            if (EnableStatusEnum.正常.getValue().equals(receivableAccrued.getEnableStatusValue())){
                receivableBill.setContractId(receivableAccrued.getContractId());
                receivableAccrued.setTotalFeeAmount(receivableAccrued.getTotalFeeAmount().add(receivableBill.getBillAmount()));
                Integer flag = this.receivableAccruedServiceImpl.compileOneReceivableAccrued(receivableAccrued);
                if (flag != ResponseContext.成功.getValue().intValue()){
                    return ResponseContext.更新失败.getValue();
                }
                receivableBill.setBillOperationStatusValue(BillOperationStageEnum.已勾稽.getValue());
            }else{
                return ResponseContext.计提不存在.getValue();
            }
        }else if (BillOperationStageEnum.待确认.getValue().equals(receivableBill.getBillOperationStatusValue())){
            receivableBill.setBillOperationStatusValue(BillOperationStageEnum.已确认.getValue());
        }else {
            return ResponseContext.更新失败.getValue();
        }
        int i = this.receivableBillMapper.updateByPrimaryKey(receivableBill);
        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.更新失败.getValue();
    }

    @Override
    public Integer deleteOneReceivableBill(Integer id) {
        ReceivableBill receivableBill = this.getReceivableBill(id);
        receivableBill.setEnableStatusValue(EnableStatusEnum.弃用.getValue());
        if (BillOperationStageEnum.已勾稽.getValue().equals(receivableBill.getBillOperationStatusValue())){
            ReceivableAccrued receivableAccrued = this.receivableAccruedServiceImpl.getReceivableAccrued(id);
            receivableAccrued.setTotalFeeAmount(receivableAccrued.getTotalFeeAmount().subtract(receivableBill.getBillAmount()));
            Integer flag = this.receivableAccruedServiceImpl.compileOneReceivableAccrued(receivableAccrued);
            if (flag != ResponseContext.成功.getValue().intValue()){
                return ResponseContext.删除失败.getValue();
            }
        }
        int i = this.receivableBillMapper.updateByPrimaryKey(receivableBill);
        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.删除失败.getValue();
    }

    @Override
    public Map<Integer, BigDecimal> getMapReceivableBill() {
        Example example = new Example(ReceivableBill.class);
        example.createCriteria().andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue())
                .andLessThanOrEqualTo("billOperationStatusValue", BillOperationStageEnum.已确认.getValue());
        List<ReceivableBill> receivableBillList = this.receivableBillMapper.selectByExample(example);
        Map<Integer,BigDecimal> result = new HashMap<>();
        for (ReceivableBill receivableBill : receivableBillList) {
            if (receivableBill.getContractId() != null){
                if (result.get(receivableBill.getContractId()) == null){
                    result.put(receivableBill.getContractId(), BigDecimalUtil.ZERO);
                }
                result.put(receivableBill.getContractId(), result.get(receivableBill.getContractId()).add(receivableBill.getBillAmount()));
            }
        }
        return result;
    }
}
